package com.yc.security;

import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.yc.entities.*;
import com.yc.entities.custom.AppLoginPermissionBean;
import com.yc.service.*;
import com.yc.utils.TreeToolUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


/**
 * 查询数据库中的用户信息
 *
 * @author 库卡哈
 */
@Slf4j
@Service("jwtUserDetailsServiceImpl")
public class JwtUserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private BloodSugarUserService bloodSugarUserService;

    @Autowired
    private BloodSugarPermissionService bloodSugarPermissionService;
    @Autowired
    private BloodSugarUserRoleService bloodSugarUserRoleService;

    @Autowired
    private BloodSugarRoleService bloodSugarRoleService;

    @Autowired
    private BloodSugarDoctorService bloodSugarDoctorService;


    /**
     * 用户登录授权
     *
     * @param username
     * @return
     * @auther
     */
    @Override
    public UserDetails loadUserByUsername(String username) {
        QueryWrapper<BloodSugarUser> wrapper = new QueryWrapper<>();
        wrapper.eq("account", username);
        BloodSugarUser sugarUser = bloodSugarUserService.getOne(wrapper);

        if (sugarUser != null) {
//            LambdaQueryWrapper<BloodSugarDoctor> wrapper1 = Wrappers.lambdaQuery();
//            wrapper1.eq(BloodSugarDoctor::getDoctorId,sugarUser.getId());
//            BloodSugarDoctor one = bloodSugarDoctorService.getOne(wrapper1);
//            sugarUser.setDeanId(one.getDeanId());
            //根据账号查询用户权限信息
            List<BloodSugarPermission> bloodSugarPermissionList = bloodSugarUserService.selectPermissionInfoByUserAccount(username);

            //当前院长所有的app权限
            List<BloodSugarPermission> appAllRole;
            //过滤出当前用户下的所有pc菜单权限
            List<BloodSugarPermission> pcPermissionsTmp = new ArrayList<>();
            List<BloodSugarPermission> pcPermissions = bloodSugarPermissionList.stream().filter((f1) -> "0".equals(f1.getClientType())).collect(Collectors.toList());

            //过滤出当前用户下的所有app菜单权限
            List<BloodSugarPermission> appPermissions = bloodSugarPermissionList.stream().filter((f1) -> "1".equals(f1.getClientType())).collect(Collectors.toList());
            //根据用户id查询用户所属的角色信息
            LambdaQueryWrapper<BloodSugarUserRole> userRoleLambdaQueryWrapper = Wrappers.lambdaQuery();
            userRoleLambdaQueryWrapper.eq(BloodSugarUserRole::getUserId, sugarUser.getId());
            BloodSugarUserRole userRole = bloodSugarUserRoleService.getOne(userRoleLambdaQueryWrapper);
            BloodSugarRole role = bloodSugarRoleService.getById(userRole.getRoleId());
            //判断是否是院长
            if (!"0".equals(role.getRoleType())) {
                QueryWrapper<BloodSugarDoctor> doctorWrapper = new QueryWrapper<>();
                doctorWrapper.eq("doctor_id", sugarUser.getId());
                BloodSugarDoctor doctor = bloodSugarDoctorService.getOne(doctorWrapper);
                LambdaQueryWrapper<BloodSugarPermission> permissionWrapper = Wrappers.lambdaQuery();
                //判断如果当前登录用户是院长直接将用户id当前id,否则设置为院长id
//                doctor == null ?  : doctor.getDeanId()
                int doctorId = 0;
                if (doctor == null) {
                    doctorId = sugarUser.getId();
                } else {
                    doctorId = doctor.getDeanId();
                }
                permissionWrapper.eq(BloodSugarPermission::getDeanId, doctorId);
                //给所有用户添加患者详细和404
                pcPermissions.removeIf(permission -> "/patient".equals(permission.getPath())
                        || "/patientDetails".equals(permission.getPath())
                        || "/404".equals(permission.getPath())
                        || "*".equals(permission.getPath()));
                for (BloodSugarPermission bloodSugarPermission : pcPermissions) {
                    if ("/home".equals(bloodSugarPermission.getPath())
                            || "/record".equals(bloodSugarPermission.getPath())
                            || "/leaveHospital".equals(bloodSugarPermission.getPath())) {
                        LambdaQueryWrapper<BloodSugarPermission> lambdaQueryWrapper = Wrappers.lambdaQuery();
                        lambdaQueryWrapper.eq(BloodSugarPermission::getDeanId, doctorId).and(test -> test.eq(BloodSugarPermission::getPath, "/patient").or().eq(BloodSugarPermission::getPath, "/patientDetails"));
                        List<BloodSugarPermission> patientList = bloodSugarPermissionService.list(lambdaQueryWrapper);
                        pcPermissionsTmp.addAll(patientList);
                        pcPermissions.addAll(patientList);
                        break;
                    }
                }
                LambdaQueryWrapper<BloodSugarPermission> lambdaQueryWrapper1 = Wrappers.lambdaQuery();
                lambdaQueryWrapper1.eq(BloodSugarPermission::getDeanId, doctorId).and(test -> test.eq(BloodSugarPermission::getPath, "/404").or().eq(BloodSugarPermission::getPath, "*"));
                List<BloodSugarPermission> patientList1 = bloodSugarPermissionService.list(lambdaQueryWrapper1);
                pcPermissionsTmp.addAll(patientList1);
                pcPermissions.addAll(patientList1);

                for (BloodSugarPermission pcPermission : pcPermissions) {
                    Integer id = pcPermission.getId();
                    LambdaQueryWrapper<BloodSugarPermission> wrapper1wra = Wrappers.lambdaQuery();
                    wrapper1wra.eq(BloodSugarPermission::getParentId, id);
                    wrapper1wra.eq(BloodSugarPermission::getDeanId, doctorId);
                    List<BloodSugarPermission> list = bloodSugarPermissionService.list(wrapper1wra);
                    if (list != null && list.size() > 0) {
                        pcPermissionsTmp.addAll(list);
                    }
                }

                appAllRole = bloodSugarPermissionService.list(permissionWrapper);
            } else {
                appAllRole = bloodSugarPermissionService.list();
            }

            //过滤出所有的app权限
            List<BloodSugarPermission> collect = appAllRole.stream().filter(f1 -> "1".equals(f1.getClientType())).collect(Collectors.toList());
            //菜单生成工具
            TreeToolUtils treeToolUtils = new TreeToolUtils(pcPermissions.stream().filter(f1 -> f1.getParentId() == 0).collect(Collectors.toList()), pcPermissionsTmp.stream().filter(f1 -> f1.getParentId() != 0).collect(Collectors.toList()));
            JSONObject pcMenuDepartmentId = new JSONObject();
            //将每个菜单对应的id存储,以便查询不同菜单的科室使用
            pcPermissions.forEach(f1 -> pcMenuDepartmentId.put(f1.getPath(), f1.getId()));
            //获取pc的菜单栏
            pcPermissions = treeToolUtils.getTree();
            log.info(String.valueOf(treeToolUtils));
            //spring权限信息
            List<String> authorities = Lists.newArrayList();

            //设置pc端的权限信息
            pcPermissions.forEach((f1) -> authorities.add(f1.getRoles()));
            //设置app端的权限信息
            appPermissions.forEach((f1) -> authorities.add(f1.getRoles()));
            JwtUser jwtUser = new JwtUser(RandomUtil.randomString(8), username, sugarUser.getPassword(), authorities, "0".equals(sugarUser.getIsDisable()));
            //将菜单对应的id,设置到jwt user可以返回给前端
            jwtUser.setPcMenuDepartmentId(pcMenuDepartmentId);
            List<AppLoginPermissionBean> roleMap = new ArrayList<>();
            //对app端的菜单设置以及菜单对应的科室id
            collect.forEach(c -> {
                AppLoginPermissionBean appLoginPermissionBean = new AppLoginPermissionBean(0, c.getTitle(), false);
                appPermissions.forEach(a -> {
                    if (c.getTitle().equals(a.getTitle())) {
                        appLoginPermissionBean.setIsHavePer(true);
                        appLoginPermissionBean.setPerId(c.getId());
                        appLoginPermissionBean.setTitleName(c.getTitle());
                    }
                });
                roleMap.add(appLoginPermissionBean);
            });
            jwtUser.setAppCustomInfo(roleMap);
            JSONArray pcArray = JSONArray.parseArray(JSON.toJSONString(pcPermissions));
            jwtUser.setPcCustomInfo(pcArray);
            return jwtUser;
        } else {
            throw new UsernameNotFoundException(String.format("No user found with username '%s'.", username));
        }
    }
}
